This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

At the very beginning is an (optional) YAML header surrounded by ---s, the header specifies useful meta data.

Below the header is the first code chunk, this chunk sets global options that apply to every chunk in your file. This is done by calling knitr::opts_chunk$set in this code chunk. Note that these global defaults can be overwritten in individual chunk headers. include = FALSE prevents both codes and results from appearing.

To understand echo = TRUE, message = FALSE and warning = FALSE, read RMarkdown tips and tricks. Energetic Students: read the “Shortening knit time” section and try it in this file

Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Cmd+Shift+Enter.

Add a new chunk by clicking the Insert Chunk button on the toolbar or by pressing Cmd+Option+I.

When you save the notebook, an HTML file containing the code and output will be saved alongside it (click the Preview button or press Cmd+Shift+K to preview the HTML file).

Exercise 8 from ISLR Chapter 2

The following illustrate commands for exploring this exercise using R and various packages for the College data.

Libraries

Try to load the ISLR library

library(ISLR)

If it is not available you will need to install the library from CRAN. Click on Packages in the lower right pane, and then Install. Enter the package name then click on the Install button.

You can also install from the console/command line using install.packages("ISLR").

Ready?

Getting the College data

Next we will need to load the dataset. This is part of the library so we will not need to read it in using read.csv but rather we will use the data function to load it from the library.

data(College)

This loads the dataframe College. Note you can always see the content of any R object by simply typing its name.

College

For information about the variables, read the text or enter

help(College)

The info will appear in the help tab.

To see explore the data, you can use the command View(College).

This will open a new tab, where you may scroll left and right to look at the rows and columns. In the View you should see that the first column is the College/University name. These can be extracted using rownames(College). Let’s print out the first 5

rownames(College)[1:5]
[1] "Abilene Christian University" "Adelphi University"           "Adrian College"              
[4] "Agnes Scott College"          "Alaska Pacific University"   

Summary

summary(College)
 Private        Apps           Accept          Enroll       Top10perc       Top25perc    
 No :212   Min.   :   81   Min.   :   72   Min.   :  35   Min.   : 1.00   Min.   :  9.0  
 Yes:565   1st Qu.:  776   1st Qu.:  604   1st Qu.: 242   1st Qu.:15.00   1st Qu.: 41.0  
           Median : 1558   Median : 1110   Median : 434   Median :23.00   Median : 54.0  
           Mean   : 3002   Mean   : 2019   Mean   : 780   Mean   :27.56   Mean   : 55.8  
           3rd Qu.: 3624   3rd Qu.: 2424   3rd Qu.: 902   3rd Qu.:35.00   3rd Qu.: 69.0  
           Max.   :48094   Max.   :26330   Max.   :6392   Max.   :96.00   Max.   :100.0  
  F.Undergrad     P.Undergrad         Outstate       Room.Board       Books           Personal   
 Min.   :  139   Min.   :    1.0   Min.   : 2340   Min.   :1780   Min.   :  96.0   Min.   : 250  
 1st Qu.:  992   1st Qu.:   95.0   1st Qu.: 7320   1st Qu.:3597   1st Qu.: 470.0   1st Qu.: 850  
 Median : 1707   Median :  353.0   Median : 9990   Median :4200   Median : 500.0   Median :1200  
 Mean   : 3700   Mean   :  855.3   Mean   :10441   Mean   :4358   Mean   : 549.4   Mean   :1341  
 3rd Qu.: 4005   3rd Qu.:  967.0   3rd Qu.:12925   3rd Qu.:5050   3rd Qu.: 600.0   3rd Qu.:1700  
 Max.   :31643   Max.   :21836.0   Max.   :21700   Max.   :8124   Max.   :2340.0   Max.   :6800  
      PhD            Terminal       S.F.Ratio      perc.alumni        Expend     
 Min.   :  8.00   Min.   : 24.0   Min.   : 2.50   Min.   : 0.00   Min.   : 3186  
 1st Qu.: 62.00   1st Qu.: 71.0   1st Qu.:11.50   1st Qu.:13.00   1st Qu.: 6751  
 Median : 75.00   Median : 82.0   Median :13.60   Median :21.00   Median : 8377  
 Mean   : 72.66   Mean   : 79.7   Mean   :14.09   Mean   :22.74   Mean   : 9660  
 3rd Qu.: 85.00   3rd Qu.: 92.0   3rd Qu.:16.50   3rd Qu.:31.00   3rd Qu.:10830  
 Max.   :103.00   Max.   :100.0   Max.   :39.80   Max.   :64.00   Max.   :56233  
   Grad.Rate     
 Min.   : 10.00  
 1st Qu.: 53.00  
 Median : 65.00  
 Mean   : 65.46  
 3rd Qu.: 78.00  
 Max.   :118.00  

Dimensions of Data

How many observations and variables are in the dataframe?

[1] 777  18

Suppose we want to refer to those numbers in the text. We can extract them using n = 777 and d = 18. Look at the code to see how we extracted them.

Scatter plot matrices

There base R version of scatter plot matrices is obtained using the pairs function to plot all variables versus each other. We can use subsetting of columns of the dataframe to look at the first 5 columns.

We can also look at this using the ggpairs function. Install the library GGally if it is not available (and any dependent libraries) and load it.

library(GGally)
ggpairs(College, columns= c(1,3:5, 2))

The last variable, 2 in this case, refers to our response variable.

Note ggpairs will show its progress in your output and using warning=FALSE or message=FALSE does not suppress it. This answer on this Stackexchange post: provided the trick or progress=F to suppress the progress bar.

gp = ggpairs(College, columns= c(1,3:5, 2))
print(gp, progress=F)

The ggpairs function realizes that the variable Private is categorial and plots side by side histograms. The density plots are also useful for seeing the skewness in the marginal distributions.

What other features do these plots indicate? (Think about assumptions for linear regression)

New variables

Let’s create a new variable Elite by binning the Top10perc variable. We are going to divide universities into two groups based on whether or not the proportion of students coming from the top 10% of their high school classes exceeds 50 %. We will use the library dplyr to illustrate some of the possible transformations and the idea of pipes (%>%), which are quite powerful once you get the hang of them!

For students who are unfamiliar with dplyr, read this intro first.

library(dplyr)
College = College %>% 
  mutate(Elite = factor(Top10perc > 50)) %>%
  mutate(Elite = 
           recode(Elite, 'TRUE' = "Yes", 'FALSE'="No"))
  

What is the above doing? Document the code here.

Compare to the base R code:

Elite=rep("No",nrow(College))
Elite[College$Top10perc >50]="Yes"
Elite=as.factor(Elite)
college=data.frame(College ,Elite)

How many Elite universities are there?

summary(College$Elite)
 No Yes 
699  78 

Side by Side Boxplots

Let’s plot the variable Outstate versus Elite using side-by-side boxplots. Using base R we would enter

boxplot(Outstate ~ Elite, data=College, 
        ylab="Outstate", xlab="Elite")
title("Distribution of Out of State Tuition")

Now for the ggplot version:

library(ggplot2)
my.bp <<-ggplot(data=College, aes(y= Outstate, x=Elite)) # Creates boxplots
my.bp <- my.bp + geom_boxplot() # Adds color
my.bp <- my.bp + ggtitle("Distribution of Out of State Tuition") # Adds a title
my.bp <- my.bp +  ylab("Outstate") + xlab("Elite") # Adds lables for axes
my.bp # displays the boxplots

Conditional Plots

Let’s look at the distribution of Out of state tuition versus Elite status for Private versus Public universities using conditional plots

coplot(Outstate ~ Elite | Private, data=College)

ggplot conditional plot

library(ggplot2)
ggplot(College, aes(x = Elite, y = Outstate, 
                    group = Private, 
                    color = Private)) +
   geom_point() + facet_grid(.~Private) + ggtitle("Distribution of Out of State Tuition") 

Next Steps

Update this document and explore the other variables thinking about the objective of predicting Apps. Document what you discover thinking about models to predict Apps.

Fit a linear model

Use the lm function as described in class to fit a linear model with Apps as the response variable and add one of the predictors in place of XXX below.

For the fitted model, produce diagnostic plots

Discuss whether the model seems appropriate in terms of assumptions.

Updating your work on GitHub

In the upper right you should see a tab labeled Git. Click on that to see a list of files that have been added/changed.

To save changes to github, check the box of any file to add/update. Then click on the Commit link (just above path). In the pop-up window add a Commit message (something meaningful that identifies the changes made). When done, click on Commit to save the changes. Click on the Green Up arrow to push your changes to Github.

Note: Update 8/29/2019 we are still waiting on the github classroom permissions, so you will not be able to push your changes to the class organization site.

LS0tCnRpdGxlOiAiRGVtbyBSU3R1ZGlvIGFuZCBFREEiCmF1dGhvcjogQ2F0aHkgTGVlCm91dHB1dDoKICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQKICBodG1sX25vdGVib29rOiBkZWZhdWx0CiAgaHRtbF9kb2N1bWVudDogZGVmYXVsdAotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlID0gRkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UpCmBgYAoKVGhpcyBpcyBhbiBbUiBNYXJrZG93bl0oaHR0cDovL3JtYXJrZG93bi5yc3R1ZGlvLmNvbSkgTm90ZWJvb2suIFdoZW4geW91IGV4ZWN1dGUgY29kZSB3aXRoaW4gdGhlIG5vdGVib29rLCB0aGUgcmVzdWx0cyBhcHBlYXIgYmVuZWF0aCB0aGUgY29kZS4KCkF0IHRoZSB2ZXJ5IGJlZ2lubmluZyBpcyBhbiAob3B0aW9uYWwpIFlBTUwgaGVhZGVyIHN1cnJvdW5kZWQgYnkgYC0tLWBzLCB0aGUgaGVhZGVyIHNwZWNpZmllcyB1c2VmdWwgbWV0YSBkYXRhLiAKCkJlbG93IHRoZSBoZWFkZXIgaXMgdGhlIGZpcnN0IGNvZGUgY2h1bmssIHRoaXMgY2h1bmsgc2V0cyBnbG9iYWwgb3B0aW9ucyB0aGF0IGFwcGx5IHRvIGV2ZXJ5IGNodW5rIGluIHlvdXIgZmlsZS4gVGhpcyBpcyBkb25lIGJ5IGNhbGxpbmcgYGtuaXRyOjpvcHRzX2NodW5rJHNldGAgaW4gdGhpcyBjb2RlIGNodW5rLiBOb3RlIHRoYXQgdGhlc2UgZ2xvYmFsIGRlZmF1bHRzIGNhbiBiZSBvdmVyd3JpdHRlbiBpbiBpbmRpdmlkdWFsIGNodW5rIGhlYWRlcnMuIGBpbmNsdWRlID0gRkFMU0VgIHByZXZlbnRzIGJvdGggY29kZXMgYW5kIHJlc3VsdHMgZnJvbSBhcHBlYXJpbmcuCgpUbyB1bmRlcnN0YW5kIGBlY2hvID0gVFJVRWAsIGBtZXNzYWdlID0gRkFMU0VgIGFuZCBgd2FybmluZyA9IEZBTFNFYCwgcmVhZCBbUk1hcmtkb3duIHRpcHMgYW5kIHRyaWNrc10oaHR0cDovL3d3dy5zY2llbmNlLnNtaXRoLmVkdS9+YW1jbmFtYXJhL3NkczI5MS9STWFya2Rvd25UaXBzLmh0bWwpLiBfRW5lcmdldGljIFN0dWRlbnRzOiByZWFkIHRoZSAiU2hvcnRlbmluZyBrbml0IHRpbWUiIHNlY3Rpb24gYW5kIHRyeSBpdCBpbiB0aGlzIGZpbGVfCgpUcnkgZXhlY3V0aW5nIHRoaXMgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpSdW4qIGJ1dHRvbiB3aXRoaW4gdGhlIGNodW5rIG9yIGJ5IHBsYWNpbmcgeW91ciBjdXJzb3IgaW5zaWRlIGl0IGFuZCBwcmVzc2luZyAqQ21kK1NoaWZ0K0VudGVyKi4gCgpBZGQgYSBuZXcgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpJbnNlcnQgQ2h1bmsqIGJ1dHRvbiBvbiB0aGUgdG9vbGJhciBvciBieSBwcmVzc2luZyAqQ21kK09wdGlvbitJKi4KCldoZW4geW91IHNhdmUgdGhlIG5vdGVib29rLCBhbiBIVE1MIGZpbGUgY29udGFpbmluZyB0aGUgY29kZSBhbmQgb3V0cHV0IHdpbGwgYmUgc2F2ZWQgYWxvbmdzaWRlIGl0IChjbGljayB0aGUgKlByZXZpZXcqIGJ1dHRvbiBvciBwcmVzcyAqQ21kK1NoaWZ0K0sqIHRvIHByZXZpZXcgdGhlIEhUTUwgZmlsZSkuCgojIyAgRXhlcmNpc2UgOCBmcm9tIElTTFIgQ2hhcHRlciAyCgpUaGUgZm9sbG93aW5nIGlsbHVzdHJhdGUgY29tbWFuZHMgZm9yIGV4cGxvcmluZyB0aGlzIGV4ZXJjaXNlIHVzaW5nIFIgYW5kIHZhcmlvdXMgcGFja2FnZXMgZm9yIHRoZSBgQ29sbGVnZWAgZGF0YS4KCiMjIyBMaWJyYXJpZXMKClRyeSB0byBsb2FkIHRoZSBgSVNMUmAgbGlicmFyeQpgYGB7cn0KbGlicmFyeShJU0xSKQpgYGAKCklmIGl0IGlzIG5vdCBhdmFpbGFibGUgeW91IHdpbGwgbmVlZCB0byBpbnN0YWxsIHRoZSAgbGlicmFyeSBmcm9tIENSQU4uIENsaWNrIG9uICAqUGFja2FnZXMqIGluIHRoZSBsb3dlciByaWdodCBwYW5lLCBhbmQgIHRoZW4gKkluc3RhbGwqLiAgRW50ZXIgdGhlIHBhY2thZ2UgbmFtZSB0aGVuIGNsaWNrIG9uIHRoZSBJbnN0YWxsIGJ1dHRvbi4KCllvdSBjYW4gYWxzbyBpbnN0YWxsIGZyb20gdGhlIGNvbnNvbGUvY29tbWFuZCBsaW5lIHVzaW5nCmBpbnN0YWxsLnBhY2thZ2VzKCJJU0xSIilgLgoKUmVhZHk/CgojIyMgIEdldHRpbmcgdGhlIENvbGxlZ2UgZGF0YQoKTmV4dCB3ZSB3aWxsIG5lZWQgdG8gbG9hZCB0aGUgZGF0YXNldC4gIFRoaXMgaXMgcGFydCBvZiB0aGUgbGlicmFyeSBzbyB3ZSB3aWxsIG5vdCBuZWVkIHRvIHJlYWQgaXQgaW4gdXNpbmcgYHJlYWQuY3N2YCBidXQgcmF0aGVyIHdlIHdpbGwgdXNlIHRoZSBgZGF0YWAgZnVuY3Rpb24gdG8gbG9hZCBpdCBmcm9tIHRoZSBsaWJyYXJ5LgoKYGBge3IgZGF0YX0KZGF0YShDb2xsZWdlKQpgYGAKClRoaXMgbG9hZHMgdGhlIGRhdGFmcmFtZSBgQ29sbGVnZWAuICBOb3RlIHlvdSBjYW4gYWx3YXlzIHNlZSB0aGUgY29udGVudCBvZiBhbnkgYFJgIG9iamVjdCBieSBzaW1wbHkgdHlwaW5nIGl0cyBuYW1lLgpgYGB7ciwgZXZhbD1GQUxTRX0KQ29sbGVnZQpgYGAKCgpGb3IgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHZhcmlhYmxlcywgcmVhZCB0aGUgdGV4dCBvciBlbnRlcgpgYGB7cn0KaGVscChDb2xsZWdlKQpgYGAKClRoZSBpbmZvIHdpbGwgYXBwZWFyIGluIHRoZSBgaGVscGAgdGFiLgoKVG8gc2VlIGV4cGxvcmUgdGhlIGRhdGEsIHlvdSBjYW4gdXNlIHRoZSBjb21tYW5kIGBWaWV3KENvbGxlZ2UpYC4KClRoaXMgd2lsbCBvcGVuIGEgbmV3IHRhYiwgd2hlcmUgeW91IG1heSBzY3JvbGwgbGVmdCBhbmQgcmlnaHQgdG8gbG9vayBhdCB0aGUgcm93cyBhbmQgY29sdW1ucy4KSW4gdGhlIGBWaWV3YCB5b3Ugc2hvdWxkIHNlZSB0aGF0IHRoZSBmaXJzdCBjb2x1bW4gaXMgdGhlIENvbGxlZ2UvVW5pdmVyc2l0eSBuYW1lLiAgVGhlc2UgY2FuIGJlIGV4dHJhY3RlZCB1c2luZyBgcm93bmFtZXMoQ29sbGVnZSlgLiAgTGV0J3MgcHJpbnQgb3V0IHRoZSBmaXJzdCA1CgpgYGB7cn0Kcm93bmFtZXMoQ29sbGVnZSlbMTo1XQpgYGAKCgoKIyMjIFN1bW1hcnkKCmBgYHtyfQpzdW1tYXJ5KENvbGxlZ2UpCmBgYAoKIyMjIERpbWVuc2lvbnMgb2YgRGF0YQoKSG93IG1hbnkgb2JzZXJ2YXRpb25zIGFuZCB2YXJpYWJsZXMgYXJlIGluIHRoZSBkYXRhZnJhbWU/CgoKYGBge3IgZGltLCBlY2hvPUZBTFNFfQpkID0gZGltKENvbGxlZ2UpCmQKYGBgCgpTdXBwb3NlIHdlIHdhbnQgdG8gcmVmZXIgdG8gdGhvc2UgbnVtYmVycyBpbiB0aGUgdGV4dC4gIFdlIGNhbiBleHRyYWN0IHRoZW0gdXNpbmcgbiA9IGByIGRbMV1gIGFuZCBkID0gYHIgZFsyXWAuCkxvb2sgYXQgdGhlIGNvZGUgdG8gc2VlIGhvdyB3ZSBleHRyYWN0ZWQgdGhlbS4gICAKCiMjIyBTY2F0dGVyIHBsb3QgbWF0cmljZXMKClRoZXJlIGBiYXNlYCBgUmAgdmVyc2lvbiBvZiBzY2F0dGVyIHBsb3QgbWF0cmljZXMgaXMgb2J0YWluZWQgdXNpbmcgdGhlIGBwYWlyc2AgZnVuY3Rpb24gdG8gcGxvdCBhbGwgdmFyaWFibGVzIHZlcnN1cyBlYWNoIG90aGVyLiAgV2UgY2FuIHVzZSBzdWJzZXR0aW5nIG9mIGNvbHVtbnMgb2YgdGhlIGRhdGFmcmFtZSB0bwpsb29rIGF0IHRoZSBmaXJzdCA1IGNvbHVtbnMuICAKCmBgYHtyLCBmaWcud2lkdGg9OH0KcGFpcnMoQ29sbGVnZVssIDE6NV0pCgpgYGAKCldlIGNhbiBhbHNvIGxvb2sgYXQgdGhpcyB1c2luZyB0aGUgYGdncGFpcnNgIGZ1bmN0aW9uLgpJbnN0YWxsIHRoZSBsaWJyYXJ5IGBHR2FsbHlgIGlmIGl0IGlzIG5vdCBhdmFpbGFibGUgKGFuZCBhbnkgZGVwZW5kZW50IGxpYnJhcmllcykgYW5kIGxvYWQgaXQuCgpgYGB7ciBnZ3BhaXJzLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBmaWcud2lkdGg9OH0KbGlicmFyeShHR2FsbHkpCmdncGFpcnMoQ29sbGVnZSwgY29sdW1ucz0gYygxLDM6NSwgMikpCmBgYAoKVGhlIGxhc3QgdmFyaWFibGUsIGAyYCBpbiB0aGlzIGNhc2UsIHJlZmVycyB0byAgb3VyIHJlc3BvbnNlIHZhcmlhYmxlLgoKTm90ZSBgZ2dwYWlyc2Agd2lsbCBzaG93IGl0cyBwcm9ncmVzcyBpbiB5b3VyIG91dHB1dCBhbmQgdXNpbmcgd2FybmluZz1GQUxTRSBvciBtZXNzYWdlPUZBTFNFIGRvZXMgbm90IHN1cHByZXNzIGl0LiBUaGlzIGFuc3dlciBvbiBbdGhpcyBTdGFja2V4Y2hhbmdlIHBvc3Q6XShodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzQxNTc3MzYyL3N1cHByZXNzLWdncGFpcnMtbWVzc2FnZXMtd2hlbi1nZW5lcmF0aW5nLXBsb3QpIHByb3ZpZGVkIHRoZSB0cmljayBvciBgcHJvZ3Jlc3M9RmAgdG8gc3VwcHJlc3MgdGhlIHByb2dyZXNzIGJhci4KCmBgYHtyIGdncGFpcnMtZ29vZCwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0naGlkZScsIGZpZy53aWR0aD04fQpncCA9IGdncGFpcnMoQ29sbGVnZSwgY29sdW1ucz0gYygxLDM6NSwgMikpCnByaW50KGdwLCBwcm9ncmVzcz1GKQpgYGAKClRoZSBgZ2dwYWlyc2AgZnVuY3Rpb24gcmVhbGl6ZXMgdGhhdCB0aGUgdmFyaWFibGUgYFByaXZhdGVgIGlzIGNhdGVnb3JpYWwgYW5kIHBsb3RzIHNpZGUgYnkgc2lkZSBoaXN0b2dyYW1zLiAgVGhlIGRlbnNpdHkgcGxvdHMgYXJlIGFsc28gdXNlZnVsIGZvciBzZWVpbmcgdGhlIHNrZXduZXNzIGluIHRoZSBtYXJnaW5hbCBkaXN0cmlidXRpb25zLgoKV2hhdCBvdGhlciBmZWF0dXJlcyBkbyB0aGVzZSBwbG90cyBpbmRpY2F0ZT8gIF8oVGhpbmsgYWJvdXQgYXNzdW1wdGlvbnMgZm9yIGxpbmVhciByZWdyZXNzaW9uKV8KCgojIyMgTmV3IHZhcmlhYmxlcwoKTGV0J3MgY3JlYXRlIGEgbmV3IHZhcmlhYmxlIGBFbGl0ZWAgYnkgYmlubmluZyB0aGUgYFRvcDEwcGVyY2AgdmFyaWFibGUuIFdlIGFyZSBnb2luZyB0byBkaXZpZGUgdW5pdmVyc2l0aWVzIGludG8gdHdvIGdyb3VwcyBiYXNlZCBvbiB3aGV0aGVyIG9yIG5vdCB0aGUgcHJvcG9ydGlvbiBvZiBzdHVkZW50cyBjb21pbmcgZnJvbSB0aGUgdG9wIDEwJSBvZiB0aGVpciBoaWdoIHNjaG9vbCBjbGFzc2VzIGV4Y2VlZHMgNTAgJS4gIFdlIHdpbGwgdXNlIHRoZSBsaWJyYXJ5IGBkcGx5cmAgdG8gaWxsdXN0cmF0ZSBzb21lIG9mIHRoZSBwb3NzaWJsZSB0cmFuc2Zvcm1hdGlvbnMgYW5kIHRoZSBpZGVhIG9mIHBpcGVzIChgJT4lYCksIHdoaWNoIGFyZSBxdWl0ZSBwb3dlcmZ1bCBvbmNlIHlvdSBnZXQgdGhlIGhhbmcgb2YgdGhlbSEKCkZvciBzdHVkZW50cyB3aG8gYXJlIHVuZmFtaWxpYXIgd2l0aCBgZHBseXJgLCByZWFkIHRoaXMgW2ludHJvXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvZHBseXIvdmlnbmV0dGVzL2RwbHlyLmh0bWwpIGZpcnN0LgoKYGBge3J9CmxpYnJhcnkoZHBseXIpCkNvbGxlZ2UgPSBDb2xsZWdlICU+JSAKICBtdXRhdGUoRWxpdGUgPSBmYWN0b3IoVG9wMTBwZXJjID4gNTApKSAlPiUKICBtdXRhdGUoRWxpdGUgPSAKICAgICAgICAgICByZWNvZGUoRWxpdGUsICdUUlVFJyA9ICJZZXMiLCAnRkFMU0UnPSJObyIpKQogIApgYGAKCgpfV2hhdCBpcyB0aGUgYWJvdmUgZG9pbmc/XyAgICBEb2N1bWVudCB0aGUgY29kZSBoZXJlLgoKQ29tcGFyZSB0byB0aGUgYmFzZSBgUmAgY29kZToKCmBgYHtyLCBldmFsdWF0ZT1GQUxTRX0KRWxpdGU9cmVwKCJObyIsbnJvdyhDb2xsZWdlKSkKRWxpdGVbQ29sbGVnZSRUb3AxMHBlcmMgPjUwXT0iWWVzIgpFbGl0ZT1hcy5mYWN0b3IoRWxpdGUpCmNvbGxlZ2U9ZGF0YS5mcmFtZShDb2xsZWdlICxFbGl0ZSkKYGBgCgpfSG93IG1hbnkgRWxpdGUgdW5pdmVyc2l0aWVzIGFyZSB0aGVyZT9fCgpgYGB7cn0Kc3VtbWFyeShDb2xsZWdlJEVsaXRlKQpgYGAKCiMjIyBTaWRlIGJ5IFNpZGUgQm94cGxvdHMKCkxldCdzIHBsb3QgdGhlIHZhcmlhYmxlIGBPdXRzdGF0ZWAgdmVyc3VzIGBFbGl0ZWAgdXNpbmcgc2lkZS1ieS1zaWRlIGJveHBsb3RzLiAgVXNpbmcgYGJhc2UgUmAgd2Ugd291bGQgZW50ZXIKCmBgYHtyLCBmaWcud2lkdGg9Nn0KYm94cGxvdChPdXRzdGF0ZSB+IEVsaXRlLCBkYXRhPUNvbGxlZ2UsIAogICAgICAgIHlsYWI9Ik91dHN0YXRlIiwgeGxhYj0iRWxpdGUiKQp0aXRsZSgiRGlzdHJpYnV0aW9uIG9mIE91dCBvZiBTdGF0ZSBUdWl0aW9uIikKYGBgCgoKTm93IGZvciB0aGUgYGdncGxvdGAgdmVyc2lvbjoKCgpgYGB7ciwgZmlnLndpZHRoPTZ9CmxpYnJhcnkoZ2dwbG90MikKbXkuYnAgPDwtZ2dwbG90KGRhdGE9Q29sbGVnZSwgYWVzKHk9IE91dHN0YXRlLCB4PUVsaXRlKSkgIyBDcmVhdGVzIGJveHBsb3RzCm15LmJwIDwtIG15LmJwICsgZ2VvbV9ib3hwbG90KCkgIyBBZGRzIGNvbG9yCm15LmJwIDwtIG15LmJwICsgZ2d0aXRsZSgiRGlzdHJpYnV0aW9uIG9mIE91dCBvZiBTdGF0ZSBUdWl0aW9uIikgIyBBZGRzIGEgdGl0bGUKbXkuYnAgPC0gbXkuYnAgKyAgeWxhYigiT3V0c3RhdGUiKSArIHhsYWIoIkVsaXRlIikgIyBBZGRzIGxhYmxlcyBmb3IgYXhlcwpteS5icCAjIGRpc3BsYXlzIHRoZSBib3hwbG90cwpgYGAKCgojIyMgQ29uZGl0aW9uYWwgUGxvdHMKCkxldCdzIGxvb2sgYXQgdGhlIGRpc3RyaWJ1dGlvbiBvZiBPdXQgb2Ygc3RhdGUgdHVpdGlvbiB2ZXJzdXMgRWxpdGUgc3RhdHVzIGZvciBQcml2YXRlIHZlcnN1cyBQdWJsaWMgdW5pdmVyc2l0aWVzIHVzaW5nIF9jb25kaXRpb25hbCBwbG90c18KCmBgYHtyLCBmaWcud2lkdGg9OH0KY29wbG90KE91dHN0YXRlIH4gRWxpdGUgfCBQcml2YXRlLCBkYXRhPUNvbGxlZ2UpCmBgYAoKCiMjICBnZ3Bsb3QgY29uZGl0aW9uYWwgcGxvdAoKYGBge3IsIGZpZy53aWR0aD02LCBlY2hvPVRSVUV9CmxpYnJhcnkoZ2dwbG90MikKZ2dwbG90KENvbGxlZ2UsIGFlcyh4ID0gRWxpdGUsIHkgPSBPdXRzdGF0ZSwgCiAgICAgICAgICAgICAgICAgICAgZ3JvdXAgPSBQcml2YXRlLCAKICAgICAgICAgICAgICAgICAgICBjb2xvciA9IFByaXZhdGUpKSArCiAgIGdlb21fcG9pbnQoKSArIGZhY2V0X2dyaWQoLn5Qcml2YXRlKSArIGdndGl0bGUoIkRpc3RyaWJ1dGlvbiBvZiBPdXQgb2YgU3RhdGUgVHVpdGlvbiIpIAoKYGBgCgoKIyMgTmV4dCBTdGVwcwoKVXBkYXRlIHRoaXMgZG9jdW1lbnQgYW5kIGV4cGxvcmUgdGhlIG90aGVyIHZhcmlhYmxlcyB0aGlua2luZyBhYm91dCB0aGUgb2JqZWN0aXZlIG9mIHByZWRpY3RpbmcgYEFwcHNgLiAgRG9jdW1lbnQgd2hhdCB5b3UgZGlzY292ZXIgdGhpbmtpbmcgYWJvdXQgbW9kZWxzIHRvIHByZWRpY3QgYEFwcHNgLgoKIyMgRml0IGEgbGluZWFyIG1vZGVsCgpVc2UgdGhlIGBsbWAgZnVuY3Rpb24gYXMgZGVzY3JpYmVkIGluIGNsYXNzIHRvIGZpdCBhIGxpbmVhciBtb2RlbCB3aXRoIGBBcHBzYCBhcyB0aGUgcmVzcG9uc2UgdmFyaWFibGUgYW5kIGFkZCAgb25lIG9mIHRoZSBwcmVkaWN0b3JzIGluIHBsYWNlIG9mIGBYWFhgIGJlbG93LiAgIAoKYGBge3J9CiMgYWRkIGxtIGNvZGUgaGVyZQoKbXltb2RlbCA9IGxtKEFwcHMgfiBUb3AxMHBlcmMsIGRhdGE9Q29sbGVnZSkKYGBgCgoKRm9yIHRoZSBmaXR0ZWQgbW9kZWwsIHByb2R1Y2UgZGlhZ25vc3RpYyBwbG90cwoKYGBge3J9CiMgYWRkIGRpYWdub3N0aWMgcGxvdHMgaGVyZQpwbG90KG15bW9kZWwpCmBgYAoKRGlzY3VzcyB3aGV0aGVyIHRoZSBtb2RlbCBzZWVtcyBhcHByb3ByaWF0ZSBpbiB0ZXJtcyBvZiBhc3N1bXB0aW9ucy4KCgojIyBVcGRhdGluZyB5b3VyIHdvcmsgb24gR2l0SHViCgpJbiB0aGUgdXBwZXIgcmlnaHQgeW91IHNob3VsZCBzZWUgYSB0YWIgbGFiZWxlZCBgR2l0YC4gIENsaWNrIG9uIHRoYXQgdG8gc2VlIGEgbGlzdCBvZiBmaWxlcyB0aGF0IGhhdmUgYmVlbiBhZGRlZC9jaGFuZ2VkLgoKVG8gc2F2ZSBjaGFuZ2VzIHRvIGdpdGh1YiwgY2hlY2sgdGhlIGJveCBvZiBhbnkgZmlsZSB0byBhZGQvdXBkYXRlLiAgVGhlbiBjbGljayBvbiB0aGUgYENvbW1pdGAgbGluayAoanVzdCBhYm92ZSBwYXRoKS4gIEluIHRoZSBwb3AtdXAgd2luZG93IGFkZCBhIENvbW1pdCBtZXNzYWdlIChzb21ldGhpbmcgbWVhbmluZ2Z1bCB0aGF0IGlkZW50aWZpZXMgdGhlIGNoYW5nZXMgbWFkZSkuICBXaGVuIGRvbmUsIGNsaWNrIG9uIENvbW1pdCB0byBzYXZlIHRoZSBjaGFuZ2VzLiAgQ2xpY2sgb24gdGhlIEdyZWVuIFVwIGFycm93IHRvIGBwdXNoYCB5b3VyIGNoYW5nZXMgdG8gR2l0aHViLgoKTm90ZTogIFVwZGF0ZSA4LzI5LzIwMTkgIHdlIGFyZSBzdGlsbCB3YWl0aW5nIG9uIHRoZSBnaXRodWIgY2xhc3Nyb29tIHBlcm1pc3Npb25zLCBzbyB5b3Ugd2lsbCBub3QgYmUgYWJsZSB0byBwdXNoIHlvdXIgY2hhbmdlcyB0byB0aGUgY2xhc3Mgb3JnYW5pemF0aW9uIHNpdGUuCg==